<html>

<head>
	<title>向量知识库管理</title>
	<meta charset="utf-8">
	<meta name="apple-mobile-web-app-capable" content="yes" />
	<meta name="mobile-web-app-capable" content="yes" />
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta name="viewport" content="width=400,  user-scalable=no">
	<link rel="shortcut icon" href="#" />
	<!-- <link href="https://npm.elemecdn.com/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet">
	<link href="https://npm.elemecdn.com/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
	<script src="https://npm.elemecdn.com/vue@2.x/dist/vue.min.js"></script>
	<script src="https://npm.elemecdn.com/vuetify@2.x/dist/vuetify.min.js"></script> -->

	<link href="/static/mdi_font/css/materialdesignicons.min.css" rel="stylesheet">

	<link href="/static/vuetify.min.css" rel="stylesheet">
	<script src="/static/vue.js"></script>
	<script src="/static/vue-i18n.js"></script>
	<script src="/static/vuetify.min.js"></script>
	<script src="/static/markdown-it.min.js"></script>
	<script src="/static/strings.js"></script>
	<script defer src="/static/xlsx.core.min.js"></script>
	<style>
		.v-application--wrap {
			display: unset;
			margin: 30px;
		}

		.v-sheet.v-card {
			margin: 20px;
			padding: 10px;
		}
	</style>
</head>

<body>
	<div id="app" v-cloak>
		<v-app>
			<h1>向量知识库管理工具</h1>
			<v-card elevation="2">
				<v-card-title>知识库选择和管理</v-card-title>
				<v-divider></v-divider><br>
				<v-card-text>
					<v-row>
						<v-col cols="12" sm="6">
							<v-combobox v-model="memory_name" :items="l现有库" :label='$t("memory_name")'></v-combobox>
						</v-col>
						<v-col cols="12" sm="2">
						</v-col>
					</v-row>
				</v-card-text>
				<v-card-actions>
					<v-btn color="purple" dark size="x-large" @click="save_rtst()">
						{{$t("save_to_disk")}}
					</v-btn>
				</v-card-actions>
			</v-card>

			<v-card elevation="2">
				<v-card-title>批量上传</v-card-title>
				<v-divider></v-divider><br>
				<v-card-text>
					<v-data-table :headers="[{ text: '问题', value: '问题' },{ text: '回答', value: '回答' }]"
						:items="l表格读取结果"></v-data-table>
				</v-card-text>
				<v-card-actions>
					<v-btn color="purple" dark size="x-large" @click="f载入表格()">
						载入表格
					</v-btn>
					<v-btn color="purple" dark size="x-large" @click="f载入自动总结问题json()">
						载入问题JSON
					</v-btn>
					<v-btn color="purple" dark size="x-large" @click="f保存自动总结问题()">
						保存问题为表格
					</v-btn>
					<v-btn color="purple" dark size="x-large" @click="f批量上传()" :loading="b批量上传中">
						{{$t("upload")}}

					</v-btn><template v-if="b批量上传中">{{i批量上传进度}}/{{l表格读取结果.length}}</template>
				</v-card-actions>
			</v-card>
			<v-card elevation="2">
				<v-card-title>测试查询</v-card-title>
				<v-divider></v-divider><br>
				<v-card-text>
					<v-row>
						<v-col cols="12" sm="6">
							<v-text-field v-model="test_zsk_prompt" label="关键词" clearable></v-text-field>

						</v-col>
						<v-col cols="12" sm="6">
							<v-text-field v-model="test_zsk_step" label="上下文数量" clearable></v-text-field>
						</v-col>
					</v-row>

					<v-data-table
						:headers="[{ text: '来源', value: 'title' },{ text: '分数', value: 'score' },{ text: '内容', value: 'content' }]"
						:items="zhishiku" hide-default-footer></v-data-table>
				</v-card-text>
				<v-card-actions>
					<v-btn color="purple" dark size="x-large"
						@click="find_in_memory(test_zsk_prompt,test_zsk_step,memory_name)">
						查询
					</v-btn>
				</v-card-actions>
			</v-card>
			<v-card elevation="2">
				<v-card-title>单条上传</v-card-title>
				<v-divider></v-divider><br>
				<v-card-text>
					<v-row>
						<v-col cols="12" sm="6">
							<v-text-field v-model="title" :label='$t("title")' clearable></v-text-field>
						</v-col>
						<v-col cols="12" sm="6">
						</v-col>
						<v-textarea :placeholder='$t("content")' v-model="content">
						</v-textarea>
					</v-row>
				</v-card-text>
				<v-card-actions>
					<v-btn color="purple" dark size="x-large" @click="upload_rtst_zhishiku(title,content)">
						{{$t("upload")}}
					</v-btn>
				</v-card-actions>
			</v-card>
		</v-app>
	</div>
	<script>
		f读取现有库 = async () => {

			response = await fetch("/api/list_rtst_in_disk", {
				method: 'post',
			})
			let list_rtst_in_disk = await response.json()
			list_rtst_in_disk = list_rtst_in_disk.map(decodeURI)
			let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
			genID = () => 'xxxxxxxxxxxx'.replace(/x/g, function () {
				return chars[Math.random() * 62 | 0]
			})
			if (!localStorage['wenda_rtst_ID']) localStorage['wenda_rtst_ID'] = genID()
			list_rtst_in_disk.push(localStorage['wenda_rtst_ID'])
			app.l现有库 = list_rtst_in_disk
		}
		app = new Vue({
			el: '#app',
			vuetify: new Vuetify(),
			i18n: i18n,
			data: () => ({
				content: '',
				title: '',
				memory_name: 'default',
				test_zsk_prompt: "",
				test_zsk_step: 1,
				zhishiku: [],
				l表格读取结果: [],
				b批量上传中: false,
				i批量上传进度: 0,
				l现有库: []
			}),
			methods: {
			}
		})
		f读取现有库()
		find_in_memory = async (s, step, memory_name) => {
			response = await fetch("/api/find_rtst_in_memory", {
				method: 'post',
				body: JSON.stringify({
					prompt: s,
					step: step,
					memory_name: encodeURI(app.memory_name)
				}),
				headers: {
					'Content-Type': 'application/json'
				}
			})
			let json = await response.json()
			console.table(json)
			app.zhishiku = json
			return json
		}
		upload_rtst_zhishiku = async (title, txt, show_result = true) => {
			response = await fetch("/api/upload_rtst_zhishiku", {
				method: 'post',
				body: JSON.stringify({
					title: title,
					txt: txt,
					memory_name: encodeURI(app.memory_name)
				}),
				headers: { 'Content-Type': 'application/json' }
			})
			show_result && alert(await response.text())
		}
		save_rtst = async () => {
			response = await fetch("/api/save_rtst_zhishiku", {
				method: 'post',
				body: JSON.stringify({
					memory_name: encodeURI(app.memory_name)
				}),
				headers: { 'Content-Type': 'application/json' }
			})
			alert(await response.text())
		}
		f载入表格 = async () => {
			await new Promise(resolve => {
				let input = document.createElement('input')
				input.type = 'file'
				input.accept = '.xlsx'
				input.onchange = function () {
					var file = input.files[0];
					var reader = new FileReader();
					reader.onload = function (e) {
						let contents = e.target.result;
						var workbook = XLSX.read(new Uint8Array(contents), {
							type: 'array'
						});
						app.l表格读取结果 = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]])
						resolve()
					};
					reader.readAsArrayBuffer(file);
				}
				input.click()
			})
		}

		f载入自动总结问题json = async () => {
			let contents = ''
			await new Promise(resolve => {
				let input = document.createElement('input')
				input.type = 'file'
				input.accept = '.json'
				input.onchange = function () {
					var file = input.files[0];
					var reader = new FileReader();
					reader.onload = function (e) {
						contents = e.target.result;
						resolve()
					};
					reader.readAsText(file);
				}
				input.click()
			})
			contents = JSON.parse(contents)
			let l = [];
			contents.forEach(e => { e.question.forEach(qa => { l.push({ 问题: qa.Q, 回答: qa.A, 来源: e.paragraph }) }) })
			app.l表格读取结果 = l
		}

		f保存自动总结问题 = async () => {
			let sheetName = '闻达自动总结问题'
			let wb = XLSX.utils.book_new()
			let ws = XLSX.utils.json_to_sheet(app.l表格读取结果)
			wb.SheetNames.push(sheetName)
			wb.Sheets[sheetName] = ws
			let wopts = {
				bookType: 'xlsx',
				bookSST: false,
				type: 'binary'
			};
			let wbout = XLSX.write(wb, wopts)
			let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })
			saveAs(blob, sheetName + '.xlsx')
		}
		const s2ab = s => {
			var buf;
			if (typeof ArrayBuffer !== 'undefined') {
			buf = new ArrayBuffer(s.length)
			var view = new Uint8Array(buf)
			for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
			return buf
			} else {
			buf = new Array(s.length);
			for (let i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
			return buf;
			}
		}
		function saveAs(obj, fileName) {//当然可以自定义简单的下载文件实现方式
			var tmpa = document.createElement("a");
			tmpa.download = fileName ? fileName + '.xlsx' : new Date().getTime() + '.xlsx';
			tmpa.href = URL.createObjectURL(obj); //绑定a标签
			tmpa.click(); //模拟点击实现下载

			setTimeout(function () { //延时释放
				URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
			}, 100);

		}
		f批量上传 = async () => {
			app.b批量上传中 = true
			for (question_index in app.l表格读取结果) {
				app.i批量上传进度 = question_index
				let question = app.l表格读取结果[question_index]
				await upload_rtst_zhishiku(question.问题, question.回答, false)
			}
			app.b批量上传中 = false
		}
	</script>
</body>

</html>